/**
 * Implementing roll effect on a DOM elements
 * 
 * @author  Mykhailo Stadnyk <mikhus@gmail.com>
 * @version $Rev$
 */
Jsl.extendDom( (function() {

	var

	_step = 5,
	
	_duration = 1000,
	
	C = Jsl.Collection,

	_roll = function( w, h, x, y, callback, restore) {
		this.css({ display : 'block' });
		if (x) this.css({ width : w + 'px' });
		if (y) this.css({ height : h + 'px' });
		callback && callback.call( this);
		if (restore) {
			restore.call( this);
			delete this._inRoll;
		}
	};

	return {

	rollIn : function( duration, callback, x, y) {
		C.$populate();
		if (this._inRoll) return;
		this._inRoll = true;
		this.css({ display : 'block' });
		var
			w = this.offsetWidth,
			h = this.offsetHeight,
			x = x == undefined ? true : !!x,
			y = y == undefined ? true : !!y,
			duration = duration || _duration,
			ofl = this.style.overflow,
			wd = this.style.width,
			ht = this.style.height,
			ws = this.style.whiteSpace
		;
		this.css({
			overflow : 'hidden',
			width : x ? 0 : (w + 'px'),
			height : y ? 0 : (h + 'px'),
			display : 'none',
			whiteSpace : 'nowrap'
		});
		for (i = 0; i <= 100; i += _step) {
			setTimeout( 
				_roll.bind( this,
					parseInt( i / 100 * w),
					parseInt( i / 100 * h),
					x,
					y,
					(i == 100 ? callback : null),
					(i == 100) ? function() {
						this.css({
							overflow : ofl,
							width : wd,
							height : ht,
							whiteSpace : ws
						});
					} : null
				),
				parseInt( i / 100 * duration)
			);
		}
		return this;
	},

	rollOut : function( duration, callback, x, y) {
		C.$populate();
		if (this._inRoll) return;
		this._inRoll = true;
		var
			x = x == undefined ? true : !!x,
			y = y == undefined ? true : !!y,
			duration = duration || _duration,
			ofl = this.style.overflow,
			wd = this.style.width,
			ht = this.style.height,
			ws = this.style.whiteSpace
		;
		this.css({
			overflow : 'hidden',
			display : 'block'
		});
		var
			w = this.offsetWidth,
			h = this.offsetHeight
		;
		this.css({
			width : w + 'px',
			height : h + 'px',
			whiteSpace : 'nowrap'
		});
		for (i = 0; i <= 100; i += _step) {
			setTimeout( 
				_roll.bind( this,
					parseInt( (1 - i / 100) * w),
					parseInt( (1 - i / 100) * h),
					x,
					y,
					(i == 100 ? callback : null),
					(i == 100) ? function() {
						this.css({
							overflow : ofl,
							display : 'none',
							width : wd,
							height : ht,
							whiteSpace : ws
						});
					} : null
				),
				parseInt( i / 100 * duration)
			);
		}
		return this;
	}

}})());
